/*
 * (C) 2005 National Australia Bank
 *
 * [All rights reserved]. This product and related documentation are protected
 * by copyright restricting its use, copying, distribution, and decompilation.
 * No part of this product or related documentation may be reproduced in any
 * form by any means without prior written authorization of
 * National Australia Bank. Unless otherwise arranged, third parties may not
 * have access to this product or related documents.
 */

package au.com.mason.propertyTracker.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import au.com.mason.propertyTracker.dao.MonitorDAO;
import au.com.mason.propertyTracker.domain.Property;
import au.com.mason.propertyTracker.domain.SaleProperty;
import au.com.mason.propertyTracker.domain.Search;
import au.com.mason.propertyTracker.domain.Status;
import au.com.mason.propertyTracker.domain.Suburb;
import au.com.mason.propertyTracker.dto.ChangedProperties;
import au.com.mason.propertyTracker.dto.SearchParameters;
import au.com.mason.propertyTracker.util.HttpClientWrapper;
import au.com.mason.propertyTracker.util.RealEstateResponseParser;
/**
 * Seeds customers for several functional tests.<br/>
 * <br/>
 * @version $Id: @(#) CreateCustomersDataSeeder.java@@\main\2  2009-02-18 23:21:28 GMT  p656354d $
 */
@Service
public class FindSoldUnderContractService {
	private static final Log LOG = LogFactory.getLog(FindSoldUnderContractService.class);
	private static final boolean DEBUG = false;
	
	private PropertyService propertyService;
	private MonitorDAO monitorDAO;
	private SuburbService suburbService;
	
	@Autowired
	public FindSoldUnderContractService(PropertyService propertyService, MonitorDAO monitorDAO, SuburbService suburbService) {
		this.propertyService = propertyService;
		this.monitorDAO = monitorDAO;
		this.suburbService = suburbService;
	}
	
	public void findProperties(ChangedProperties changedProperties) {
		HttpClientWrapper httpClientWrapper = new HttpClientWrapper();
		SearchParameters searchParameters = new SearchParameters();
		searchParameters.setMonitor(false);
		List<SaleProperty> properties = null; //TODO: Fix This propertyService.filterProperties(null, searchParameters);
		
		int count = 0;
		System.out.println("*********** processing find properties");
		for (SaleProperty property : properties) {
			httpClientWrapper.init(property.getUrl());
			if (!property.isRemoved() && !property.isSold()) {
				if (httpClientWrapper.isRemoved(property)) {
					property.setStatus(Status.REMOVED);
					property.setStatusDate(new Date());
					propertyService.updateProperty(property);
					changedProperties.addRemoved(property);
				}
				else {
					RealEstateResponseParser parser = new RealEstateResponseParser(httpClientWrapper.getResponse());
					if (parser.isUnderContract()) {
						if (!property.isUnderContract()) {
							//System.out.println(response.toString());
							property.setStatus(Status.UNDER_CONTRACT);
							property.setStatusDate(new Date());
							propertyService.updateProperty(property);
							changedProperties.addUnderContract(property);
						}
					}
					else if (parser.isSold()) {
						property.setStatus(Status.SOLD);
						property.setStatusDate(new Date());
						propertyService.updateProperty(property);
						changedProperties.addSold(property);
					}
					else if (property.isUnderContract()) {
						changedProperties.addChanged(property);
					}
					/*else if (!property.isIgnorePriceChanged()) {
						BigDecimal[] prices = parser.getPrices(property.getStreetAddress(), DEBUG);
						if (!property.getPriceFrom().equals(prices[0]) || (property.getPriceTo() != null && !property.getPriceTo().equals(prices[1]))) {
							changedProperties.addPropertyChangedPrice(property);
						}
					}*/
				}
				
				count++;
				
				if (count%10 == 0) System.out.println("processed - " + count);
			}
		}
	}
	
	public void findRentals(ChangedProperties changedProperties) {
		HttpClientWrapper httpClientWrapper = new HttpClientWrapper();
		SearchParameters searchParameters = new SearchParameters();
		
		searchParameters.setRental(true);
		searchParameters.setMonitor(false);
		List<Property> rentals = propertyService.filterProperties(null, searchParameters);
		
		int count = 0;
		System.out.println("*********** processing find rental properties");
		for (Property property : rentals) {
			httpClientWrapper.init(property.getUrl());
			if (!property.isRemoved()) {
				if (httpClientWrapper.isRemoved(property)) {
					property.setStatus(Status.REMOVED);
					property.setStatusDate(new Date());
					propertyService.updateProperty(property);
					changedProperties.addRemovedRental(property);
				}
				
				count++;
				
				if (count%10 == 0) System.out.println("processed - " + count);
			}
		}
	}

	public List<String> findNewRentals() {
		List<String> messages = new ArrayList<String>();
		HttpClientWrapper httpClientWrapper = new HttpClientWrapper();
		List<Search> monitors = monitorDAO.getMonitors(true, true);
		
		for (Search monitor : monitors) {
			httpClientWrapper.initAndExecute(monitor.getUrl());
			
			RealEstateResponseParser parser = new RealEstateResponseParser(httpClientWrapper.getResponse());
			
			int newProperties = 0;
			List<String> urls = parser.getUrls();
			
			for (String propertyUrl : urls) {
				httpClientWrapper.initAndExecute(propertyUrl);
				
				RealEstateResponseParser propertyParser = new RealEstateResponseParser(httpClientWrapper.getResponse());
				BigDecimal propertyId = propertyParser.getPropertyId();
				Property property = propertyService.findByPropertyId(propertyId);
				
				if (property == null) {
					System.out.println("url - " + propertyUrl);
					newProperties++;
					//TODO: need to fix this
					SaleProperty newProperty = propertyParser.getSaleProperty(propertyUrl);
					newProperty.setUrl(propertyUrl);
					Suburb suburb = suburbService.getSuburb(propertyParser.getSuburbName(), propertyParser.getPostcode());
					newProperty.setSuburb(suburb);
					
					propertyService.saveProperty(newProperty);
				}
				
			}
			
			messages.add("New properties for <SUBURB> - " + newProperties);
		}
		
		return messages;
	}

}
